package cn.akwangl.socket.bio;

import lombok.extern.slf4j.Slf4j;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;

/**
 * Socket BIO 模型测试.Client 端实现.
 * <p>
 * 模拟一个多人群聊功能实现.
 *
 * @author 阿坤同学
 * @date 2022/6/18 15:26
 * @since 0.0.6
 */
@Slf4j
public class ChatClient {

    public volatile boolean flag = true;

    private String hostname;
    private int port;
    private Socket serverSocket;
    private DataInputStream in;
    private DataOutputStream out;

    public ChatClient(String hostname, int port) {
        this.hostname = hostname;
        this.port = port;
    }

    public String readMessage() {
        String clientMsg = null;
        try {
            clientMsg = in.readUTF();
        } catch (IOException e) {
            log.warn("客户端与服务器断开连接,获取消息失败");
        }
        return clientMsg;
    }

    public void sendMessage(String message) {
        try {
            out.writeUTF(message);
        } catch (IOException e) {
            log.warn("{}消息发送失败,socket 连接已断开.", message);
        }
    }

    public void start() {
        InetSocketAddress inetSocketAddress = new InetSocketAddress(hostname, port);
        serverSocket = new Socket();

        try {
            serverSocket.connect(inetSocketAddress);
            in = new DataInputStream(serverSocket.getInputStream());
            out = new DataOutputStream(serverSocket.getOutputStream());

            // 发送消息
            new Thread(new UserInputHandler(this)).start();

            // 读取服务端消息
            while (flag) {
                String serverMsg = readMessage();
                log.info("server msg:{}", serverMsg);
            }

            if (!flag) {
                close();
            }
        } catch (IOException e) {
            log.error("server socket 连接失败.", e);
        } finally {
            close();
        }
    }

    public boolean hasCommandQuit(String message) {
        return ChatService.QUIT.equals(message);
    }

    public void close() {
        if (!serverSocket.isClosed()) {
            try {
                out.close();
                in.close();
                serverSocket.close();
                log.info("客户端已断开连接...");
            } catch (IOException e) {
                log.error("socket 关闭失败", e);
            }
        }
    }

    public static void main(String[] args) {
        ChatClient chatClient = new ChatClient(ChatService.SERVER_ADDRESS, ChatService.DEFAULT_SERVER_PORT);
        chatClient.start();
    }
}
